import { ElMessage, ElNotification, ElLoading} from 'element-plus'

export interface L0 {
    k: string; // log category (e.g., 'info', 'debug', 'error')
    t: Date; // timestamp
    s: string; // log message
};

export class U2 {
    static ld1: ElLoading | null = null;
    static start_loading(t: string = "Loading...") {
        // console.log("Starting loading...with t = ", t);
        if (arguments.length === 0 || !t) {
            t = "Loading"
        }
        U2.ld1 = ElLoading.service({lock: true, text: t, background: 'rgba(255,255,255, 0.7)',});
        return true;
    }
    static stop_loading() {
        console.log("Stopping loading...");
        if (U2.ld1) {U2.ld1.close(); U2.ld1 = null;}
        console.log("Loading stopped");
        return false
    }
    static showError(o: string){
        console.log(`❌️ ${o}`)
        ElNotification({
            title: 'Error',
            message: o,
            type: 'error',
        });
    }

    static showSuccess(o: string){
        ElNotification({
            title: 'Success',
            message: o,
            type: 'error',
        });
    }


    static parseLogs(s: string, valid_tags: string[]): L0[] {
        function parseNextTag(s: string): [L0, string] {
            // return [L0, the rest of the string];

            // 1. parse till the first tag
            while (s[0] !== '<') {
                s = s.slice(1);
            }
            // now s starts with '<'
            // console.log(`🦜 :1. now s = ${s}`);

            // 2. get the tag name <tagName time="iso-str">
            let i = s.indexOf(' '); // tag Name end
            if (i === -1) {
                throw new Error('Tag name not found');
            }
            const n = s.slice(1, i); // tag name
            // 3. advance and get the time attribute
            s = s.slice(i + 1); // remove tag name and space
            // console.log(`🦜 :2. now s = ${s}`);
            if (! s.startsWith('time=')) {
                throw new Error('Time attribute not found');
            }
            const j = s.indexOf('>'); // end of tag
            if (j === -1) {
                throw new Error('Time attribute not found');
            }
            const time = s.slice(5, j); // extract time value

            // console.log(`🦜 3. time = ${time}`);
            // 4. now s starts with '>' and we can extract the content
            s = s.slice(j + 1); // remove time attribute and '>'
            let o = ''
            const te = '</' + n + '>';
            while (!s.startsWith(te)) {
                o += s[0];
                s = s.slice(1);
            }
            // now s starts with '</tagName>', so we can remove it
            s = s.slice(te.length);

            // console.log(`🦜 :4. now s = ${s}`);
            // console.log(`🦜 :4. now o = ${o}`);

            return [{ k: n, t: new Date(time), s: o }, s];
        }

        s = s.trim();
        try {
            
            let o = [];
            while (s.length > 0) {
                let x = null;
                [x, s] = parseNextTag(s);
                if (!valid_tags.includes(x.k)) {
                    x.k += '[invalid-tag]';
                }
                o.push(x);
                s = s.trim();
            }
            return o;
        } catch (e) {
            // console.error('Error parsing logs:', e);
            return [
                { k: 'log-parsing-error', t: new Date(), s: `Error parsing logs: ${e.message}` }
            ];
        }
    }
}

export function humanizeBytes(bytes, si = false, dp = 1) {
    const thresh = si ? 1000 : 1024;

    if (Math.abs(bytes) < thresh) {
        return bytes + ' B';
    }

    const units = si
        ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
        : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];

    let u = -1;
    const r = 10 ** dp;

    do {
        bytes /= thresh;
        ++u;
    } while (Math.abs(bytes) >= thresh && u < units.length - 1);

    return Math.round(bytes * r) / r + ' ' + units[u];
}

export function humanizeTimespanSec(s: number) {
    return humanizeTimespan(s * 1000);
}

export function humanizeTimespan(milliseconds) {
    const seconds = Math.floor(milliseconds / 1000);
    const minutes = Math.floor(seconds / 60);
    const hours = Math.floor(minutes / 60);
    const days = Math.floor(hours / 24);

    let result = [];

    if (days > 0) {
        result.push(`${days} day${days > 1 ? 's' : ''}`);
    }
    if (hours % 24 > 0) {
        result.push(`${hours % 24} hour${hours % 24 > 1 ? 's' : ''}`);
    }
    if (minutes % 60 > 0) {
        result.push(`${minutes % 60} minute${minutes % 60 > 1 ? 's' : ''}`);
    }
    if (seconds % 60 > 0) {
        result.push(`${seconds % 60} second${seconds % 60 > 1 ? 's' : ''}`);
    }

    return result.join(', ') || '0 seconds'; // Handle zero duration
}

// console.log(humanizeTimespan(361000)); // Output: "6 minutes, 1 second"
// console.log(humanizeTimespan(86400000)); // Output: "1 day"
